package com.yitao.cms.service.sms;

import com.skipper.base.bean.DataOutput;
import com.skipper.base.json.JSON;
import com.skipper.base.service.GenericEntityService;
import com.skipper.base.utils.DateUtil;
import com.yitao.client.dto.sms.SmsMessagesDto;
import com.yitao.client.dto.sms.SmsSendRequestDto;
import com.yitao.client.dto.sms.SmsSendResponseDto;
import com.yitao.client.model.sms.QSmsMessagesModel;
import com.yitao.client.model.sms.SmsMessagesModel;
import com.yitao.cms.constant.SmsMessagesConstant;
import com.yitao.cms.utils.BaseUtils;
import com.yitao.cms.utils.DateUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;

import static java.time.temporal.ChronoUnit.MINUTES;

@Service
public class SmsMessagesService extends GenericEntityService<SmsMessagesModel, SmsMessagesDto, QSmsMessagesModel> {

    private BaseUtils instance = BaseUtils.getInstance();

    @Value("${messages.account}")
    private String account;
    @Value("${messages.password}")
    private String password;
    @Value("${messages.url}")
    private String smsSingleRequestServerUrl;
    @Value("${messages.sign_key}")
    private String signKey;
    @Value("${sms_restrict}")
    private Boolean smsRestrict;

    private static final String REPORT = "false";

    private static final String EXTEND = "123";

    public SmsMessagesService(EntityManager entityManager) {
        super(entityManager);
    }

    //验证码
    @Transactional
    public DataOutput getCode(HttpServletRequest request, String phone) {
        //1分钟2条一小时5条 一天10条呢
        Date date = new Date();
        StringBuffer stringBuffer = new StringBuffer();
        String code = groupVerifyCode();
        String ipAdrress = BaseUtils.getIpAdrress(request);
        if (smsRestrict) {
            //限制天数
            if (queryFactory.select(Q).from(Q).where(Q.userPhone.eq(phone).and(Q.sendDate.gt(DateUtils.getDayStartTime(date))).and(Q.sendDate.lt(DateUtils.getDayEndTime(date)))).fetchCount() >= 30) {
                return instance.getMyErrorMsg("验证码已超过限制次数");
            }
            //限制小时
            if (queryFactory.select(Q).from(Q).where(Q.userPhone.eq(phone).and(Q.sendDate.gt(DateUtil.minus(date, 60, MINUTES))).and(Q.sendDate.lt(date))).fetchCount() >= 10) {
                return instance.getMyErrorMsg("验证码已超过限制次数");
            }
            //分钟限制
            if (queryFactory.select(Q).from(Q).where(Q.userPhone.eq(phone).and(Q.sendDate.gt(DateUtil.minus(date, 1, MINUTES))).and(Q.sendDate.lt(date))).fetchCount() >= 5) {
                return instance.getMyErrorMsg("验证码已超过限制次数");
            }
            //限制IP
            if (queryFactory.select(Q).from(Q).where(Q.createIp.eq(ipAdrress).and(Q.sendDate.gt(DateUtils.getDayStartTime(date))).and(Q.sendDate.lt(DateUtils.getDayEndTime(date)))).fetchCount() >= 100) {
                return instance.getMyErrorMsg("警告：您好，您的短信发送过多请勿再次发送");
            }
        }
        stringBuffer.append(signKey).append("您的验证码是:").append(code).append(",验证码有效时间为").append(SmsMessagesConstant.SMS_LIMITATION).append("分钟，请勿将验证码泄露给他人，如非您本人操作，请忽略本短信。");
        SmsSendRequestDto smsSingleRequest = new SmsSendRequestDto(account, password, stringBuffer.toString(), phone.trim(), REPORT, EXTEND);
        smsSingleRequest.setSendtime(DateUtil.getYesterDayDate("yyyyMMddHHss"));
        String requestJson = JSON.toJSONString(smsSingleRequest);
        //System.out.println("before request string is: " + requestJson);
        String response = sendSmsByPost(smsSingleRequestServerUrl, requestJson);
        //System.out.println("response after request result is :" + response);
        SmsSendResponseDto smsSingleResponse = JSON.parseObject(response, SmsSendResponseDto.class);
        //System.out.println("response  toString is :" + smsSingleResponse);
        SmsMessagesModel smsMessagesModel = new SmsMessagesModel();
        smsMessagesModel.setUserPhone(phone);
        smsMessagesModel.setContent(stringBuffer.toString());
        smsMessagesModel.setCreateTime(date);
        smsMessagesModel.setSendDate(date);
        smsMessagesModel.setCreateIp(ipAdrress);
        smsMessagesModel.setCreateBy(-1l);
        smsMessagesModel.setIsDelete(SmsMessagesConstant.YesOrNoEnum.NO.getCode());
        smsMessagesModel.setMsgStatus(SmsMessagesConstant.ResponseDtoEnum.SUCCESS.getValue());
        smsMessagesModel.setMsgType(SmsMessagesConstant.ResponseDtoEnum.SUCCESS.getValue());
        smsMessagesModel = addMessages(smsMessagesModel);
        if (smsSingleResponse.getCode().equals(SmsMessagesConstant.ResponseDtoEnum.SUCCESS.getValue().toString())) {
            //发送成功
            return new DataOutput(code);
        }

        smsMessagesModel.setMsgStatus(SmsMessagesConstant.ResponseDtoEnum.FAILURE.getValue());
        smsMessagesModel.setRemark(smsSingleResponse.getErrorMsg());
        //发送失败
        addMessages(smsMessagesModel);
        return new DataOutput(smsSingleResponse.getCode(), smsSingleResponse.getErrorMsg());
    }


    /**
     * @param path        地址
     * @param postContent 内容
     * @return String
     * @throws
     * @author tianyh
     * @Description
     */
    private String sendSmsByPost(String path, String postContent) {
        URL url = null;
        try {
            url = new URL(path);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setRequestMethod("POST");// 提交模式
            httpURLConnection.setConnectTimeout(10000);//连接超时 单位毫秒
            httpURLConnection.setReadTimeout(10000);//读取超时 单位毫秒
            // 发送POST请求必须设置如下两行
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
            httpURLConnection.setRequestProperty("Content-Type", "application/json");

//			PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
//			printWriter.write(postContent);
//			printWriter.flush();

            httpURLConnection.connect();
            OutputStream os = httpURLConnection.getOutputStream();
            os.write(postContent.getBytes("UTF-8"));
            os.flush();

            StringBuilder sb = new StringBuilder();
            int httpRspCode = httpURLConnection.getResponseCode();
            if (httpRspCode == HttpURLConnection.HTTP_OK) {
                // 开始获取数据
                BufferedReader br = new BufferedReader(
                        new InputStreamReader(httpURLConnection.getInputStream(), "utf-8"));
                String line = null;
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
                br.close();
                return sb.toString();

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private String groupVerifyCode() {
        String verifyCode = "";
        for (int i = 0; i < 4; i++) {
            verifyCode += String.valueOf(((int) Math.floor(Math.random() * 9 + 1)));
        }
        return verifyCode;
    }


    @Transactional
    public SmsMessagesModel addMessages(SmsMessagesModel smsMessagesModel) {
        SmsMessagesModel save = repository.save(smsMessagesModel);
        return save;
    }
}
